﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Gaiocorp.SLMapViewer.Legend;
using System.Xml;
using System.IO;
using System.Windows.Media.Imaging;
using Gaiocorp.SLMapViewer.Resources;

namespace Gaiocorp.SLMapViewer
{
    public partial class LegendControl : UserControl
    {
        #region Private Members
        //private MapControlBase _ParentMap;
        private MapControl _ParentMap;
        private Color _titleColor = Colors.Black;
        private Color _backroundColor = Colors.White;
        private double _bakOpacity = 1.0;
        #endregion

        #region Public Properties
        public IDictionary<string, string> _parameters = null;
       
        public MapControl ParentMap
        {
            get { return _ParentMap; }
            set { _ParentMap = value; }
        }
        public Color BackroundColor
        {
            get { return _backroundColor; }
            set
            {
                _backroundColor = value;
                this.gridLegend.Background = new SolidColorBrush(_backroundColor);

            }
        }
        public Color TitleColor
        {
            get { return _titleColor; }
            set
            {
                _titleColor = value;
            }
        }
        public double BackgroundOpacity
        {
            get { return _bakOpacity; }
            set
            {
                _bakOpacity = value;
                this.gridLegend.Opacity = _bakOpacity;
            }
        }
        #endregion
       
        private LegendLayers allLyrs = new LegendLayers();
        string xmlString = string.Empty;
        
        public LegendControl()
        {
            InitializeComponent();
            this.Loaded += new RoutedEventHandler(Page_Loaded);
        }

        void Page_Loaded(object sender, RoutedEventArgs e)
        {
        
        }

        #region Legend
        /// <summary>
        /// Populates the allLyrs (LegendLayers) object from the xmlResponse string
        /// </summary>
        /// <param name="xmlResponse"></param>
        /// <returns>LegendLayers object</returns>
        public LegendLayers PopulateLegend(string xmlResponse)
        {
            bool hasActiveLayer = false;
            allLyrs.Clear();

            MapToolBar mapTools = (MapToolBar)ParentMap.FindName("mapTools");
            TextBox stxtRequest = (TextBox)ParentMap.FindName("stxtRequest");
            TextBox stxtActiveLayer = (TextBox)ParentMap.FindName("stxtActiveLayer");
            TextBox stxtActiveLayerName = (TextBox)ParentMap.FindName("stxtActiveLayerName");
            TextBlock txbLayerInfo = (TextBlock)ParentMap.FindName("txbLayerInfo");
            if (xmlResponse == string.Empty)
            {
                mapTools.SelectImg_rect.Visibility = Visibility.Collapsed;
                mapTools.SelectImg.Visibility = Visibility.Collapsed;
                mapTools.InfoImg_rect.Visibility = Visibility.Collapsed;
                mapTools.InfoImg.Visibility = Visibility.Collapsed;
                return null;
            }

            XmlReaderSettings settings = new XmlReaderSettings();
            settings.XmlResolver = new XmlXapResolver();
            XmlReader reader = XmlReader.Create(new StringReader(xmlResponse));
            reader.MoveToContent();
            LegendLayer aLayer = new LegendLayer();

            int iLyrCount = 0;
            while (reader.Read())
            {
                if (reader.NodeType == XmlNodeType.Element && reader.Name == "LAYER")
                {
                    aLayer = new LegendLayer();
                    aLayer.Name = reader.GetAttribute("name").ToString();
                    aLayer.Title = reader.GetAttribute("title").ToString();
                    aLayer.Group = reader.GetAttribute("group").ToString();
                    aLayer.Index = Convert.ToInt32(reader.GetAttribute("index").ToString());
                    aLayer.Visible = Convert.ToBoolean(Convert.ToInt32(reader.GetAttribute("isvisible").ToString()));
                    aLayer.Active = Convert.ToBoolean(Convert.ToInt32(reader.GetAttribute("isactive").ToString()));
                    aLayer.IsAnnotation = Convert.ToBoolean(Convert.ToInt32(reader.GetAttribute("annotation").ToString()));
                    aLayer.EnableActive = Convert.ToBoolean(Convert.ToInt32(reader.GetAttribute("canbeactive").ToString()));
                    aLayer.XLinkField = reader.GetAttribute("xlinkfield").ToString();
                    aLayer.HLinkField = reader.GetAttribute("hlink").ToString();
                    aLayer.HLinkParams = reader.GetAttribute("hparams").ToString();
                    if (aLayer.Active)
                    {
                        hasActiveLayer = true;
                        stxtActiveLayer.Text = iLyrCount.ToString();
                        stxtActiveLayerName.Text = aLayer.Name;
                        txbLayerInfo.Text = Gaiocorp.SLMapViewer.Resources.ApplicationStrings.ActiveLayer.ToString() + " " + aLayer.Title;
                    }
                    aLayer.IdField = reader.GetAttribute("idfield").ToString();
                    aLayer.IdField = reader.GetAttribute("idname").ToString();
                    iLyrCount++;
                }

                if (reader.NodeType == XmlNodeType.Element && reader.Name == "FIELD")
                {
                    aLayer.Fields.Add(new LayerField(reader.GetAttribute("name").ToString()));
                }

                if (reader.NodeType == XmlNodeType.Element && reader.Name == "CLASS")
                {
                    aLayer.Symbols.Add(new LegendSymbol(reader.GetAttribute("name").ToString(), reader.GetAttribute("symbolURL").ToString()));
                }
                if (reader.NodeType == XmlNodeType.Element && reader.Name == "SUBLAYER")
                {
                    aLayer.SubLayers.Add(reader.GetAttribute("name").ToString());
                }


                if (reader.NodeType == XmlNodeType.EndElement && reader.Name == "LAYER")
                {
                    allLyrs.Add(aLayer);
                }

                if (reader.NodeType == XmlNodeType.EndElement && reader.Name == "LEGEND")
                {
                    break;
                }
            }

            reader.Close();
            if (!hasActiveLayer)
            {
                mapTools.SelectImg_rect.Visibility = Visibility.Collapsed;
                mapTools.SelectImg.Visibility = Visibility.Collapsed;
                mapTools.InfoImg_rect.Visibility = Visibility.Collapsed;
                mapTools.InfoImg.Visibility = Visibility.Collapsed;
                mapTools.HyperlImg_rect.Visibility = Visibility.Collapsed;
                mapTools.HyperlImg.Visibility = Visibility.Collapsed;
            }
            else
            {
                mapTools.SelectImg_rect.Visibility = Visibility.Visible;
                mapTools.SelectImg.Visibility = Visibility.Visible;
                mapTools.InfoImg_rect.Visibility = Visibility.Visible;
                mapTools.InfoImg.Visibility = Visibility.Visible;

                LegendLayer activeLayer = allLyrs.getActiveLayer();
                if (activeLayer != null)
                {
                    if (activeLayer.HLinkField != "NONE")
                    {
                        mapTools.HyperlImg_rect.Visibility = Visibility.Visible;
                        mapTools.HyperlImg.Visibility = Visibility.Visible;
                    }
                    else
                    {
                        mapTools.HyperlImg_rect.Visibility = Visibility.Collapsed;
                        mapTools.HyperlImg.Visibility = Visibility.Collapsed;
                    }
                }
            }
            //Draw Legend control
            DrawLegendTree();
            return allLyrs;
        }
        /// <summary>
        /// Treeview node clicked event
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="xmlRequest"></param>
        private void nodeClicked(object sender, string xmlRequest)
        {
            TextBox stxtRequest = (TextBox)ParentMap.FindName("stxtRequest");
            if (xmlRequest != string.Empty)
            { stxtRequest.Text = xmlRequest; }
        }
        /// <summary>
        /// Draws the Legend based on the Layer Collection object (allLyrs)
        /// </summary>
        private void DrawLegendTree()
        {
            int i = 0;
            XmlReaderSettings settings = new XmlReaderSettings();
            settings.XmlResolver = new XmlXapResolver();
            string strRequest = ((TextBox)ParentMap.FindName("stxtRequest")).Text;
            string action = strRequest.Split(' ')[1].Split('=')[1];
            if (action.ToUpper() == "INITMAP")
            {
                gridLegend.Tag = null;
            }
            List<string> groupList = new List<string>();

            // Loop to create layers and symbols
            foreach (LegendLayer obj in allLyrs)
            {
                if (gridLegend.Tag == null) // Only go through this the first time
                {
                    TreeViewItem nodeLayer = new TreeViewItem();
                    nodeLayer.AddHandler(TreeViewItem.MouseLeftButtonDownEvent, new MouseButtonEventHandler(nodeLayer_MouseLeftButtonDown), true);
                    TreeViewNodeLayer tvnl = new TreeViewNodeLayer(obj.Index, ParentMap.Parameters["SessionID"].ToString());
                    tvnl.LayerName = obj.Name;
                    tvnl.IsActive = obj.Active;
                    tvnl.TitleColor=this.TitleColor;
                    tvnl.BackgroundOpacity = this.BackgroundOpacity;
                    tvnl.BackroundColor = this.BackroundColor;
                    tvnl.Clicked += new TreeViewNodeLayer.LegendControl_Clicked(nodeClicked);
                    nodeLayer.Header = tvnl;
                    nodeLayer.DataContext = obj;
                    TreeViewItem groupLayer = new TreeViewItem();
                    if (obj.Group != string.Empty)
                    {
                        if (!groupList.Contains(obj.Group))
                        {
                            groupLayer = new TreeViewItem();
                            TreeViewLayerGroup tvlg = new TreeViewLayerGroup();
                            tvlg.GroupName = obj.Group;
                            groupLayer.Header = tvlg;
                            tvlg.TitleColor = tvnl.TitleColor;
                            tvlg.BackroundColor = tvnl.BackroundColor;
                            tvlg.BackgroundOpacity = tvnl.BackgroundOpacity;
                            treeLegend1.Items.Add(groupLayer);
                            //Check the group node if at least one layer is visible
                            if (obj.Visible) { tvlg.chkBoxGroup.IsChecked = true; }
                            groupList.Add(obj.Group);

                        }
                        else
                        {
                            foreach (TreeViewItem item in treeLegend1.Items)
                            {
                                if (item.Header.GetType() == typeof(TreeViewLayerGroup))
                                {
                                    TreeViewLayerGroup header = (TreeViewLayerGroup)item.Header;
                                    if (header.GroupName == obj.Group)
                                    { groupLayer = item; }
                                }
                            }
                        }
                        groupLayer.Items.Add(nodeLayer);
                    }
                    else { treeLegend1.Items.Add(nodeLayer); }
                    //Increment counter
                    i++;
                    //Start creating the symbols for each layer
                    foreach (LegendSymbol objSym in obj.Symbols)
                    {
                        Image tempImg = new Image();
                        if (obj.IsAnnotation != true)
                        {
                            TreeViewItem nodeClass = new TreeViewItem();
                            TreeViewNodeClass tvnc = new TreeViewNodeClass();
                            tvnc.TitleColor=tvnl.TitleColor;
                            tvnc.BackroundColor=tvnl.BackroundColor;
                            tvnc.BackgroundOpacity = tvnl.BackgroundOpacity;
                            nodeClass.Header = tvnc;
                            nodeClass.DataContext = objSym;
                            nodeLayer.Items.Add(nodeClass);
                        }
                        else
                        {
                            BitmapImage imgAnnt = new BitmapImage();
                            imgAnnt.SetSource(Gaiocorp.SLMapViewer.Resources.Images.applix);
                            TreeViewItem nodeClass = new TreeViewItem();
                            nodeClass.Header = new TreeViewNodeClass();
                            objSym.SymbolImage = (BitmapImage)imgAnnt;
                            objSym.Name = obj.Title;
                            nodeClass.DataContext = objSym;
                            nodeLayer.Items.Add(nodeClass);
                        }
                    }
                    foreach (string subLayer in obj.SubLayers)
                    {
                        TreeViewItem nodeSubL = new TreeViewItem();
                        TreeViewSubLayer tvsl = new TreeViewSubLayer();
                        tvsl.SubLayerName = subLayer;
                        nodeSubL.Header = tvsl;
                        nodeLayer.Items.Add(nodeSubL);
                    }
                }
                else
                {
                    if (obj.Active == true)
                    { SetActiveLayer(this.treeLegend1, obj.Name); }
                }
            }
            //Set the Tag of the Legend Grid to the Layers class
            if (allLyrs.Count > 0)
            { gridLegend.Tag = allLyrs; }
        }
        /// <summary>
        /// Mouse left button event for the nodeLayer item
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void nodeLayer_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            TreeViewItem nodeLayer = (TreeViewItem)sender;
            if (nodeLayer.Header.GetType() == typeof(TreeViewNodeLayer))
            { nodeClicked((TreeViewNodeLayer)nodeLayer.Header, string.Empty); }
        }
        /// <summary>
        /// Set the active layer in the legend and draw it in red
        /// </summary>
        /// <param name="legendTree"></param>
        /// <param name="sLyrName"></param>
        void SetActiveLayer(TreeView legendTree, string sLyrName)
        {
            foreach (TreeViewItem item in legendTree.Items)
            {
                if (item.Header.GetType() == typeof(TreeViewLayerGroup))
                {
                    foreach (TreeViewItem subitem in item.Items)
                    {
                        if (subitem.Header.GetType() == typeof(TreeViewNodeLayer))
                        {
                            TreeViewNodeLayer tvnl = (TreeViewNodeLayer)subitem.Header;
                            if (tvnl.LayerName == sLyrName)
                            { tvnl.IsActive = true; }
                            else { tvnl.IsActive = false; }
                        }
                    }
                }
                else if (item.Header.GetType() == typeof(TreeViewNodeLayer))
                {
                    TreeViewNodeLayer tvnl = (TreeViewNodeLayer)item.Header;
                    if (tvnl.LayerName == sLyrName)
                    { tvnl.IsActive = true; }
                    else { tvnl.IsActive = false; }
                }
            }
        }
        /// <summary>
        /// Deprecated
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void xbtnCloseLegend_Click(object sender, RoutedEventArgs e)
        {
            this.cnvLegend.Visibility = Visibility.Collapsed;
        }
        #endregion
    }
}
